#include "fxcc/imgui/Editor.h"
#include "fxcc/core/audio/openal/Maps.h"
#include "fxcc/core/audio/openal/AudioSource.h"
#include "fxcc/core/audio/openal/Resources.h"

using namespace fxcc::imgui;
using namespace fxcc::audio::openal;

template<>
bool Editor::ComboFromResource<AudioClipMap>(const std::string& label, AudioClipMap& t)
{
    bool flag{ 0 };
    std::string name1 = t.m_Desc.GetFilePath();

     auto& rs = fxcc::audio::openal::Resources::Inst();

    if (ImGui::BeginCombo(label.c_str(), name1.c_str()))
    {
        for (const auto [key, value] : rs.m_AudioSources.m_DataList)
        {
            ImGui::PushID(value.get());
            std::string name2 = key.GetFilePath();
            if ( ImGui::Selectable(name2.c_str(), name1 == name2))
            {
                t.m_Desc = value->m_Desc;
                t.m_Value = value;

            }
            ImGui::PopID();
        }

        ImGui::EndCombo();
    }

    if (ImGui::BeginDragDropTarget()) {
        if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("File")) {
            using T = fxcc::File;
            const T receivedData = *(const T*)payload->Data;
            
            fxcc::audio::openal::AudioSource::Desc desc;
            if (desc.SetPath(receivedData.m_RelativePath))
            {
                t.m_Desc = desc;
                if (t.m_Value)
                {
                    t.m_Value->Stop();
                }
                t.m_Value = rs.m_AudioSources.Register(desc);

            }
        }
        ImGui::EndDragDropTarget();
    }

    ImGui::Text("");

    if (t.m_Value)
    {
        ImGui::SameLine();
        if (ImGui::Button("PL"))
            t.m_Value->Play();
        ImGui::SameLine();
        if (ImGui::Button("PA"))
            t.m_Value->Pause();
        ImGui::SameLine();
        if (ImGui::Button("S"))
            t.m_Value->Stop();
    }


    return flag;
};

template<>
bool Editor::ComboFromResource<AudioSource::Desc>(const std::string& label, AudioSource::Desc& t)
{
    bool flag{ 0 };
    std::string name1 = t.GetFilePath();

    const auto& rs = fxcc::audio::openal::Resources::Inst();

    if (ImGui::BeginCombo(label.c_str(), name1.c_str()))
    {
        for (const auto [key, value] : rs.m_AudioSources.m_DataList)
        {
            ImGui::PushID(value.get());
            std::string name2 = key.GetFilePath();
            if (flag |= ImGui::Selectable(name2.c_str(), name1 == name2))
            {
                t = value->m_Desc;
            }
            ImGui::PopID();

        }


        ImGui::EndCombo();
    }

    return flag;
};

template <>
bool Editor::Edit<AudioClipMap>(const std::string& label, AudioClipMap& inst)
{
    auto& resource = Resources::Inst();

    bool combo = ImGui::BeginCombo(label.c_str(), inst.m_Desc.GetFilePath().c_str());

    if(combo)
    {
        for (auto [key, value] : resource.m_AudioSources.m_DataList)
        {
            if (ImGui::Selectable(key.GetFilePath().c_str(), key == inst.m_Desc))
            {
                inst.m_Desc = key;
                inst.m_Value = value;
            }
        }
        ImGui::EndCombo();
    }

    if (inst.m_Value)
    {
        EditInst<AudioSource>("audioSource", *inst.m_Value);
    }

    return false;
}

template <>
bool Editor::Edit<AudioSource::Desc>(const std::string& label, AudioSource::Desc& inst)
{
    static std::map<AudioSource::Desc::Type, std::string> ls =
    {
      { AudioSource::Desc::Type::_Wav_ ,"_Wav_ "},
      { AudioSource::Desc::Type::_Ogg_,"_Ogg_" }

    };
    ComboEnumMap< AudioSource::Desc::Type>("Type",inst.m_Type, ls);

    switch (inst.m_Type)
    {
    case AudioSource::Desc::Type::_Wav_:
        EditInst<std::string>("WavPath", inst.m_WavPath);
        break;
    case AudioSource::Desc::Type::_Ogg_:
        EditInst<std::string>("OggPath", inst.m_OggPath);
        break;
    default:
        break;
    }
    return false;
}


template <>
bool Editor::Edit<AudioSource>(const std::string& label, AudioSource& inst)
{
    //EditInst<AudioSource::Desc>("Desc", inst.m_Desc);
    if (ImGui::Button("Play"))
    {
        inst.Play();
    }
    ImGui::SameLine();
    if (ImGui::Button("Pause"))
    {
        inst.Pause();
    }
    ImGui::SameLine();
    if (ImGui::Button("Stop"))
    {
        inst.Stop();
    }
    if (ImGui::Button("Setloop"))
    {
        inst.SetLooping(true);
    }
    ImGui::SameLine();

    ImGui::Text("");
    return false;
}
